//! 字符串处理工具模块
//! 
//! 对应Java中的AppStringUtils类，提供字符串判断、转换、格式化等功能

use regex::Regex;
use std::collections::HashMap;
use once_cell::sync::Lazy;

/// 正则表达式缓存
static PATTERN_CACHE: Lazy<std::sync::Mutex<HashMap<String, Regex>>> = 
    Lazy::new(|| std::sync::Mutex::new(HashMap::new()));

/// 中文字符范围常量
const CN_CHAR_START: char = '\u{4e00}';
const CN_CHAR_END: char = '\u{9fa5}';

/// 判断字符串是否为空
/// 
/// # Examples
/// ```
/// use librarys::core::string_utils::is_empty;
/// 
/// assert_eq!(is_empty(""), true);
/// assert_eq!(is_empty("  "), true);
/// assert_eq!(is_empty("hello"), false);
/// ```
pub fn is_empty(s: &str) -> bool {
    s.trim().is_empty()
}

/// 判断字符串是否不为空
/// 
/// # Examples
/// ```
/// use librarys::core::string_utils::is_not_empty;
/// 
/// assert_eq!(is_not_empty(""), false);
/// assert_eq!(is_not_empty("hello"), true);
/// ```
pub fn is_not_empty(s: &str) -> bool {
    !is_empty(s)
}

/// 检测String是否全是中文
/// 
/// # Examples
/// ```
/// use librarys::core::string_utils::is_all_chinese;
/// 
/// assert_eq!(is_all_chinese("你好"), true);
/// assert_eq!(is_all_chinese("hello"), false);
/// assert_eq!(is_all_chinese("你好world"), false);
/// ```
pub fn is_all_chinese(s: &str) -> bool {
    if s.is_empty() {
        return false;
    }
    s.chars().all(is_chinese_char)
}

/// 判定单个字符是否为中文
/// 
/// # Examples
/// ```
/// use librarys::core::string_utils::is_chinese_char;
/// 
/// assert_eq!(is_chinese_char('你'), true);
/// assert_eq!(is_chinese_char('a'), false);
/// ```
pub fn is_chinese_char(c: char) -> bool {
    c >= CN_CHAR_START && c <= CN_CHAR_END
}

/// 编译正则表达式并缓存
/// 
/// # Examples
/// ```
/// use librarys::string_utils::compile_regex;
/// 
/// let pattern = compile_regex(r"\d+").unwrap();
/// assert!(pattern.is_match("123"));
/// ```
pub fn compile_regex(pattern: &str) -> Result<Regex, regex::Error> {
    let mut cache = PATTERN_CACHE.lock().unwrap();
    
    if let Some(regex) = cache.get(pattern) {
        Ok(regex.clone())
    } else {
        let regex = Regex::new(pattern)?;
        cache.insert(pattern.to_string(), regex.clone());
        Ok(regex)
    }
}

/// 将字符串的第一位转为小写
/// 
/// # Examples
/// ```
/// use librarys::string_utils::to_lowercase_first;
/// 
/// assert_eq!(to_lowercase_first("Hello"), "hello");
/// assert_eq!(to_lowercase_first("WORLD"), "wORLD");
/// ```
pub fn to_lowercase_first(s: &str) -> String {
    if s.is_empty() {
        return String::new();
    }
    
    let mut chars: Vec<char> = s.chars().collect();
    if let Some(first_char) = chars.get_mut(0) {
        *first_char = first_char.to_lowercase().next().unwrap_or(*first_char);
    }
    chars.into_iter().collect()
}

/// 将字符串的第一位转为大写
/// 
/// # Examples
/// ```
/// use librarys::string_utils::to_uppercase_first;
/// 
/// assert_eq!(to_uppercase_first("hello"), "Hello");
/// assert_eq!(to_uppercase_first("world"), "World");
/// ```
pub fn to_uppercase_first(s: &str) -> String {
    if s.is_empty() {
        return String::new();
    }
    
    let mut chars: Vec<char> = s.chars().collect();
    if let Some(first_char) = chars.get_mut(0) {
        *first_char = first_char.to_uppercase().next().unwrap_or(*first_char);
    }
    chars.into_iter().collect()
}

/// 下划线命名转为驼峰命名
/// 
/// # Examples
/// ```
/// use librarys::string_utils::underscore_to_camel_case;
/// 
/// assert_eq!(underscore_to_camel_case("hello_world"), "helloWorld");
/// assert_eq!(underscore_to_camel_case("user_name_id"), "userNameId");
/// ```
pub fn underscore_to_camel_case(s: &str) -> String {
    if !s.contains('_') {
        return s.to_string();
    }
    
    let parts: Vec<&str> = s.split('_').collect();
    let mut result = String::new();
    
    for (i, part) in parts.iter().enumerate() {
        if i == 0 {
            result.push_str(part);
        } else {
            result.push_str(&to_uppercase_first(part));
        }
    }
    
    result
}

/// 驼峰命名法转为下划线命名
/// 
/// # Examples
/// ```
/// use librarys::string_utils::camel_case_to_underscore;
/// 
/// assert_eq!(camel_case_to_underscore("helloWorld"), "hello_world");
/// assert_eq!(camel_case_to_underscore("userNameId"), "user_name_id");
/// ```
pub fn camel_case_to_underscore(s: &str) -> String {
    let mut result = String::new();
    
    for (i, c) in s.chars().enumerate() {
        if c.is_uppercase() && i > 0 {
            result.push('_');
            result.push(c.to_lowercase().next().unwrap_or(c));
        } else {
            result.push(c);
        }
    }
    
    result
}

/// 字符串连接，将参数列表拼接为一个字符串
/// 
/// # Examples
/// ```
/// use librarys::string_utils::concat;
/// 
/// assert_eq!(concat(&["hello", "world"]), "helloworld");
/// assert_eq!(concat(&["a", "b", "c"]), "abc");
/// ```
pub fn concat(parts: &[&str]) -> String {
    parts.join("")
}

/// 字符串连接，将参数列表用分隔符拼接为一个字符串
/// 
/// # Examples
/// ```
/// use librarys::string_utils::concat_with_separator;
/// 
/// assert_eq!(concat_with_separator(&["hello", "world"], " "), "hello world");
/// assert_eq!(concat_with_separator(&["a", "b", "c"], "-"), "a-b-c");
/// ```
pub fn concat_with_separator(parts: &[&str], separator: &str) -> String {
    parts.join(separator)
}

/// 将字符串转换为ASCII十六进制表示
/// 
/// # Examples
/// ```
/// use librarys::string_utils::to_ascii_hex;
/// 
/// assert_eq!(to_ascii_hex("A"), "41");
/// ```
pub fn to_ascii_hex(s: &str) -> String {
    s.bytes()
        .map(|b| format!("{:02x}", b))
        .collect::<Vec<String>>()
        .join("")
}

/// 将字符串转换为Unicode表示
/// 
/// # Examples
/// ```
/// use librarys::string_utils::to_unicode;
/// 
/// assert_eq!(to_unicode("A"), "\\u0041");
/// ```
pub fn to_unicode(s: &str) -> String {
    s.chars()
        .map(|c| format!("\\u{:04x}", c as u32))
        .collect::<Vec<String>>()
        .join("")
}

/// 是否包含中文字符
/// 
/// # Examples
/// ```
/// use librarys::string_utils::contains_chinese;
/// 
/// assert_eq!(contains_chinese("hello世界"), true);
/// assert_eq!(contains_chinese("hello"), false);
/// ```
pub fn contains_chinese(s: &str) -> bool {
    s.chars().any(is_chinese_char)
}

/// 判断字符串是否为数字
/// 
/// # Examples
/// ```
/// use librarys::string_utils::is_number;
/// 
/// assert_eq!(is_number("123"), true);
/// assert_eq!(is_number("12.34"), true);
/// assert_eq!(is_number("abc"), false);
/// ```
pub fn is_number(s: &str) -> bool {
    is_integer(s) || is_float(s)
}

/// 判断字符串是否为整数
/// 
/// # Examples
/// ```
/// use librarys::string_utils::is_integer;
/// 
/// assert_eq!(is_integer("123"), true);
/// assert_eq!(is_integer("-456"), true);
/// assert_eq!(is_integer("12.34"), false);
/// ```
pub fn is_integer(s: &str) -> bool {
    if s.is_empty() {
        return false;
    }
    
    let regex = compile_regex(r"^[-+]?\d+$").unwrap();
    regex.is_match(s)
}

/// 判断字符串是否为浮点数
/// 
/// # Examples
/// ```
/// use librarys::string_utils::is_float;
/// 
/// assert_eq!(is_float("12.34"), true);
/// assert_eq!(is_float("-56.78"), true);
/// assert_eq!(is_float("123"), false);
/// ```
pub fn is_float(s: &str) -> bool {
    if s.is_empty() {
        return false;
    }
    
    let regex = compile_regex(r"^[-+]?\d+\.\d+$").unwrap();
    regex.is_match(s)
}

/// 判断字符串是否为布尔值
/// 
/// # Examples
/// ```
/// use librarys::string_utils::is_boolean;
/// 
/// assert_eq!(is_boolean("true"), true);
/// assert_eq!(is_boolean("false"), true);
/// assert_eq!(is_boolean("TRUE"), true);
/// assert_eq!(is_boolean("hello"), false);
/// ```
pub fn is_boolean(s: &str) -> bool {
    let lower = s.to_lowercase();
    lower == "true" || lower == "false"
}

/// 字符串转整数，失败时返回默认值
/// 
/// # Examples
/// ```
/// use librarys::string_utils::to_int_or_default;
/// 
/// assert_eq!(to_int_or_default("123", 0), 123);
/// assert_eq!(to_int_or_default("abc", 0), 0);
/// ```
pub fn to_int_or_default(s: &str, default: i32) -> i32 {
    s.parse().unwrap_or(default)
}

/// 字符串转整数
/// 
/// # Examples
/// ```
/// use librarys::string_utils::to_int;
/// 
/// assert_eq!(to_int("123"), 123);
/// assert_eq!(to_int("abc"), 0);
/// ```
pub fn to_int(s: &str) -> i32 {
    to_int_or_default(s, 0)
}

/// 字符串转长整数，失败时返回默认值
/// 
/// # Examples
/// ```
/// use librarys::string_utils::to_long_or_default;
/// 
/// assert_eq!(to_long_or_default("123456789", 0), 123456789);
/// assert_eq!(to_long_or_default("abc", 0), 0);
/// ```
pub fn to_long_or_default(s: &str, default: i64) -> i64 {
    s.parse().unwrap_or(default)
}

/// 字符串转长整数
/// 
/// # Examples
/// ```
/// use librarys::string_utils::to_long;
/// 
/// assert_eq!(to_long("123456789"), 123456789);
/// assert_eq!(to_long("abc"), 0);
/// ```
pub fn to_long(s: &str) -> i64 {
    to_long_or_default(s, 0)
}

/// 字符串转浮点数，失败时返回默认值
/// 
/// # Examples
/// ```
/// use librarys::string_utils::to_double_or_default;
/// 
/// assert_eq!(to_double_or_default("12.34", 0.0), 12.34);
/// assert_eq!(to_double_or_default("abc", 0.0), 0.0);
/// ```
pub fn to_double_or_default(s: &str, default: f64) -> f64 {
    s.parse().unwrap_or(default)
}

/// 字符串转浮点数
/// 
/// # Examples
/// ```
/// use librarys::string_utils::to_double;
/// 
/// assert_eq!(to_double("12.34"), 12.34);
/// assert_eq!(to_double("abc"), 0.0);
/// ```
pub fn to_double(s: &str) -> f64 {
    to_double_or_default(s, 0.0)
}

/// 匹配正则表达式的第一个结果
/// 
/// # Examples
/// ```
/// use librarys::string_utils::match_first;
/// 
/// assert_eq!(match_first(r"\d+", "abc123def"), Some("123".to_string()));
/// assert_eq!(match_first(r"\d+", "abcdef"), None);
/// ```
pub fn match_first(pattern: &str, text: &str) -> Option<String> {
    if let Ok(regex) = compile_regex(pattern) {
        regex.find(text).map(|m| m.as_str().to_string())
    } else {
        None
    }
}

/// 检查是否为乱码（包含过多特殊字符）
/// 
/// # Examples
/// ```
/// use librarys::core::string_utils::is_garbled;
/// 
/// assert_eq!(is_garbled("正常文本"), false);
/// assert_eq!(is_garbled("hello world"), false);
/// // 包含大量特殊符号的字符串应该被识别为乱码
/// assert_eq!(is_garbled("~`#$%^&*+=|<>"), true);
/// ```
pub fn is_garbled(s: &str) -> bool {
    if s.is_empty() {
        return false;
    }
    
    let total_chars = s.chars().count();
    let special_chars = s.chars()
        .filter(|&c| {
            // 统计非常用字符：不是字母数字、不是中文、不是基本标点和空白
            !c.is_alphanumeric() && 
            !is_chinese_char(c) && 
            !c.is_whitespace() && 
            !matches!(c, '.' | ',' | '!' | '?' | ';' | ':' | '(' | ')' | '[' | ']' | '{' | '}' | '"' | '\'' | '-' | '_' | '/' | '\\' | '@')
        })
        .count();
    
    // 如果特殊字符占比超过50%，认为是乱码
    let ratio = special_chars as f32 / total_chars as f32;
    ratio > 0.5
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_is_empty() {
        assert!(is_empty(""));
        assert!(is_empty("  "));
        assert!(is_empty("\t\n"));
        assert!(!is_empty("hello"));
    }

    #[test]
    fn test_is_chinese() {
        assert!(is_all_chinese("你好"));
        assert!(!is_all_chinese("hello"));
        assert!(!is_all_chinese("你好world"));
    }

    #[test]
    fn test_case_conversion() {
        assert_eq!(to_lowercase_first("Hello"), "hello");
        assert_eq!(to_uppercase_first("world"), "World");
    }

    #[test]
    fn test_naming_conversion() {
        assert_eq!(underscore_to_camel_case("hello_world"), "helloWorld");
        assert_eq!(camel_case_to_underscore("helloWorld"), "hello_world");
    }

    #[test]
    fn test_number_validation() {
        assert!(is_number("123"));
        assert!(is_number("12.34"));
        assert!(!is_number("abc"));
        
        assert!(is_integer("123"));
        assert!(!is_integer("12.34"));
        
        assert!(is_float("12.34"));
        assert!(!is_float("123"));
    }

    #[test]
    fn test_type_conversion() {
        assert_eq!(to_int("123"), 123);
        assert_eq!(to_int("abc"), 0);
        
        assert_eq!(to_long("123456789"), 123456789);
        assert_eq!(to_double("12.34"), 12.34);
    }

    #[test]
    fn test_is_garbled() {
        // 正常文本不应该被识别为乱码
        assert!(!is_garbled("正常文本"));
        assert!(!is_garbled("hello world"));
        assert!(!is_garbled("test@example.com"));
        assert!(!is_garbled("你好，世界!"));
        
        // 包含大量特殊符号的字符串应该被识别为乱码
        assert!(is_garbled("~`#$%^&*+=|<>"));
        assert!(is_garbled("©®™☂☃♠♥♦♣¡¿·†‡…"));
        
        // 边界情况
        assert!(!is_garbled(""));
        assert!(!is_garbled("   "));
    }
}